home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
363_01
/
insttabl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-15
|
36KB
|
1,080 lines
/***********************************************************************
*
* INSTTABLE.C
* Instruction Table for 68020 Assembler
*
* Description: This file contains two kinds of data structure declarations:
* "variant lists" and the instruction table. First in the file are
* "variant lists," one for each different instruction. Then comes the
* instruction table, which contains the mnemonics of the various
* instructions, a pointer to the variant list for each instruction, and
* other data. Finally, the variable tableSize is initialized to contain
* the number of instructions in the instruction table.
*
* Author: Paul McKee
* ECE492 North Carolina State University, 12/13/86
*
* Modified A.E. Romer, Version 1.0 16 March 1991
* 5 October 1991 - TRAP instruction got lost somehow, restored
************************************************************************/
/*********************************************************************
HOW THE INSTRUCTION TABLE AND VARIANT LISTS ARE USED
The procedure which instLookup() and assemble() use to look up
and verify an instruction (or directive) is as follows. Once the
mnemonic of the instruction has been parsed and stripped of its size
code and trailing spaces, the instLookup() does a binary search on the
instruction table to determine if the mnemonic is present. If it is
not found, then the INV_OPCODE error results. If the mnemonic is
found, then assemble() examines the field parseFlag for that entry.
This flag is TRUE if the mnemonic represents a normal instruction that
can be parsed by assemble(); it is FALSE if the instruction's operands
have an unusual format (as is the case for MOVEM and DC).
If the parseFlag is TRUE, then assemble will parse the
instruction's operands, check them for validity, and then pass the
data to the proper routine which will build the instruction. To do
this it uses the pointer in the instruction table to the instruction's
"variant list" and scans through the list until it finds an particular
"variant" of the instruction which matches the addressing mode(s)
specified. If it finds such a variant, it checks the instruction's
size code and passes the instruction mask for the appropriate size
(there are three masks for each variant) to the building routine
through a pointer in the variant list for that variant.
*********************************************************************/
#include <stdio.h>
#include "asm.h"
/* Define size code masks for instructions that allow more than one size */
#define BW (BYTE | WORD)
#define WL (WORD | LONG)
#define BWL (BYTE | WORD | LONG)
#define BL (BYTE | LONG)
/* Define the "variant lists" for each different instruction */
/* NOTE: in the following variant lists it is essential that variants that do
* not require destination (for instance 'asl' MemAlt variant) precede variants
* that do. The reason is that 'assemble' parses variants in the order of this
* listing, so if the variant in the code parsed were one that does not require
* destination, 'assemble' would try to parse the destination if the variants
* were listed in the wrong order, and fail.
*/
variant abcdva[] =
{
{ DnDirect, DnDirect, BYTE, twoReg, 0xC100, 0xC100, 0 },
{ AnIndPre, AnIndPre, BYTE, twoReg, 0xC108, 0xC108, 0 }
};
variant addva[] =
{
{ Immediate, DataAlt, BWL, immedInst, 0x0600, 0x0640, 0x0680 },
{ Immediate, AnDirect, WL, quickMath, 0, 0x5040, 0x5080 },
{ All, DnDirect, BWL, arithReg, 0xD000, 0xD040, 0xD080 },
{ DnDirect, MemAlt, BWL, arithAddr, 0xD100, 0xD140, 0xD180 },
{ All, AnDirect, WL, arithReg, 0, 0xD0C0, 0xD1C0 },
};
variant addava[] =
{
{ All, AnDirect, WL, arithReg, 0, 0xD0C0, 0xD1C0 },
};
variant addiva[] =
{
{ Immediate, DataAlt, BWL, immedInst, 0x0600, 0x0640, 0x0680 }
};
variant addqva[] =
{
{ Immediate, DataAlt, BWL, quickMath, 0x5000, 0x5040, 0x5080 },
{ Immediate, AnDirect, WL, quickMath, 0, 0x5040, 0x5080 }
};
variant addxva[] =
{
{ DnDirect, DnDirect, BWL, twoReg, 0xD100, 0xD140, 0xD180 },
{ AnIndPre, AnIndPre, BWL, twoReg, 0xD108, 0xD148, 0xD188 }
};
variant andva[] =
{
{ Data, DnDirect, BWL, arithReg, 0xC000, 0xC040, 0xC080 },
{ DnDirect, MemAlt, BWL, arithAddr, 0xC100, 0xC140, 0xC180 },
{ Immediate, DataAlt, BWL, immedInst, 0x0200, 0x0240, 0x0280 }
};
variant andiva[] =
{
{ Immediate, DataAlt, BWL, immedInst, 0x0200, 0x0240, 0x0280 },
{ Immediate, CCRDirect, BYTE, immedToCCR, 0x023C, 0x023C, 0 },
{ Immediate, SRDirect, WORD, immedWord, 0, 0x027C, 0 }
};
variant aslva[] =
{
{ MemAlt, 0, WORD, oneOp, 0, 0xE1C0, 0 },
{ DnDirect, DnDirect, BWL, shiftReg, 0xE120, 0xE160, 0xE1A0 },
{ Immediate, DnDirect, BWL, shiftReg, 0xE100, 0xE140, 0xE180 }
};
variant asrva[] =
{
{ MemAlt, 0, WORD, oneOp, 0, 0xE0C0, 0 },
{ DnDirect, DnDirect, BWL, shiftReg, 0xE020, 0xE060, 0xE0A0 },
{ Immediate, DnDirect, BWL, shiftReg, 0xE000, 0xE040, 0xE080 }
};
variant bccva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6400, 0x6400, 0x6400 }
};
variant bchgva[] =
{
{ DnDirect, MemAlt, BYTE, arithAddr, 0x0140, 0x0140, 0 },
{ DnDirect, DnDirect, LONG, arithAddr, 0, 0x0140, 0x0140 },
{ Immediate, MemAlt, BYTE, staticBit, 0x0840, 0x0840, 0 },
{ Immediate, DnDirect, LONG, staticBit, 0, 0x0840, 0x0840 }
};
variant bclrva[] =
{
{ DnDirect, MemAlt, BYTE, arithAddr, 0x0180, 0x0180, 0 },
{ DnDirect, DnDirect, LONG, arithAddr, 0, 0x0180, 0x0180 },
{ Immediate, MemAlt, BYTE, staticBit, 0x0880, 0x0880, 0 },
{ Immediate, DnDirect, LONG, staticBit, 0, 0x0880, 0x0880 }
};
variant bcsva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6500, 0x6500, 0x6500 }
};
variant beqva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6700, 0x6700, 0x6700 }
};
variant bfchgva[] =
{
{ DnDirect | CtrAlt, 0, 0, NULL, 0x0, 0xEAC0, 0x0 }
};
variant bfclrva[] =
{
{ DnDirect | CtrAlt, 0, 0, NULL, 0x0, 0xECC0, 0x0 }
};
variant bfextsva[] =
{
{ DnDirect | Control, DnDirect, 0, NULL, 0x0, 0xEBC0, 0x0 }
};
variant bfextuva[] =
{
{ DnDirect | Control, DnDirect, 0, NULL, 0x0, 0xE9C0, 0x0 }
};
variant bfffova[] =
{
{ DnDirect | Control, DnDirect, 0, NULL, 0x0, 0xEDC0, 0x0 }
};
variant bfinsva[] =
{
{ DnDirect, DnDirect | Control, 0, NULL, 0x0, 0xEFC0, 0x0 }
};
variant bfsetva[] =
{
{ DnDirect | CtrAlt, 0, 0, NULL, 0x0, 0xEEC0, 0x0 }
};
variant bftstva[] =
{
{ DnDirect | CtrAlt, 0, 0, NULL, 0x0, 0xE8C0, 0x0 }
};
variant bgeva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6C00, 0x6C00, 0x6C00 }
};
variant bgtva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6E00, 0x6E00, 0x6E00 }
};
variant bhiva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6200, 0x6200, 0x6200 }
};
variant bhsva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6400, 0x6400, 0x6400 }
};
variant bleva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6f00, 0x6F00, 0x6F00 }
};
variant blova[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6500, 0x6500, 0x6500 }
};
variant blsva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6300, 0x6300, 0x6300 }
};
variant bltva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6d00, 0x6D00, 0x6D00 }
};
variant bmiva[] =
{
{ Absolute, 0, SHORT | LONG, branch, 0x6b00, 0